package org.xtext.runtime.plan;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.xtext.runtime.interpreter.Agent;
import org.xtext.runtime.term.Variable;
import org.xtext.runtime.util.Bindings;


public class TryRecoverStep implements IPlanStep {
	private IPlanStep tryStep;
	private IPlanStep recoverStep;
	private int planState;
	
	public TryRecoverStep(IPlanStep tryStep, IPlanStep recoverStep) {
		this.recoverStep = recoverStep;
		this.tryStep = tryStep;
		planState = 0;
	}
	

	public String toString() {
		return toString("");
	}
	
	public String toString(String tabs) {
		return tabs + "try " + tryStep + "...";
	}

	public String toFullString(String tabs) {
		return tabs + "try " + tryStep.toFullString(tabs) + "\n" + tabs + "recover" + recoverStep.toFullString(tabs);
	}

	@Override
	public void handle(Agent agent, PlanStack planStack) {
		switch (planState) {
		case 0:
			recoverStep.reset();
			tryStep.reset();
//			System.out.println("[" + agent.name()+"] first invocation");
			
			planStack.back();
			planStack.addRecoveryPlan(recoverStep);
			
			planStack.addPlanStep(tryStep);
			planStack.getNextActivity().handle(agent, planStack);
			planState = 1;
			break;
		case 1:
		case 2:
//			System.out.println("[" + agent.name()+"] second invocation...");
			planState = 0;
		}
	}

	@Override
	public Set<Variable> variables() {
		Set<Variable> variables = new HashSet<Variable>();
		variables.addAll(tryStep.variables());
		variables.addAll(recoverStep.variables());
		return variables;
	}

	@Override
	public TryRecoverStep copy(Map<String, Variable> vars) {
		return new TryRecoverStep(tryStep.copy(vars), recoverStep.copy(vars));
	}

	@Override
	public TryRecoverStep apply(Bindings bindings) {
		return this;
	}

	@Override
	public void reset() {
	}
}
